package edu.sdbi.judge.service.impl;

import edu.sdbi.judge.domain.entity.AssessmentScore;
import edu.sdbi.judge.domain.entity.CopyJudge;
import edu.sdbi.judge.domain.vo.StudentResult;
import edu.sdbi.judge.exception.IllegalRequestException;
import edu.sdbi.judge.mapper.AssessmentScoreMapper;
import edu.sdbi.judge.mapper.StudentResultMapper;
import edu.sdbi.judge.service.DatainitializeService;
import edu.sdbi.judge.service.GetJudgeIpResultService;
import edu.sdbi.judge.service.JudgeService;
import edu.sdbi.judge.util.HttpUtil;
import edu.sdbi.judge.util.PlagiarismCheckerUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

@Service
public class JudgeServiceImpl implements JudgeService {

    @Autowired
    private HttpUtil httpUtil;
    @Autowired
    private DatainitializeService datainitialize;
    @Autowired
    private List<GetJudgeIpResultService> getJudgeIpResultMaps;
    @Autowired
    private StudentResultMapper studentResultMapper;

    @Override
    public List<AssessmentScore> judgeAll(String filePath) {
        List<AssessmentScore> assessmentScores = new ArrayList<>();
        File fileDir = new File(filePath);
        File[] files = fileDir.listFiles((dir, name) -> name.endsWith(".jar") || name.endsWith(".war"));
        for (File file : files) {
            AssessmentScore score = gradeJarFile(file);
            assessmentScores.add(score);
        }
        return assessmentScores;
    }

    @Override
    public List<CopyJudge> judgeCopy(String filePath) {
        List<CopyJudge> copyJudges = new ArrayList<>();
        File fileDir = new File(filePath);
        File[] files = fileDir.listFiles((dir, name) -> name.endsWith(".zip"));
        for (File file : files) {
            try {
                CopyJudge copyJudge = PlagiarismCheckerUtil.judge(file, StandardCharsets.UTF_8);
                copyJudges.add(copyJudge);
            } catch (Exception e) {
                try {
                    CopyJudge copyJudge = PlagiarismCheckerUtil.judge(file, StandardCharsets.ISO_8859_1);
                    copyJudges.add(copyJudge);
                } catch (Exception e1) {
                    System.out.println(file.getName() + "异常");
                }
            }
        }
        return copyJudges;
    }

    private AssessmentScore testOne() {
        String ip = "localhost";
        String ipPort = ip + ":8080";
        String idName;
        AssessmentScore aS = new AssessmentScore();
        try {
            try {
                // 调用HTTP GET请求方法
                idName = httpUtil.doGet(ipPort, null, null);
                // 处理返回结果
                if (idName == null) {
                    return null;
                }
            } catch (Exception e) {
                e.printStackTrace();
                throw new IllegalRequestException("HTTP请求失败:" + ipPort);
            }
            String[] parts = idName.split("-");
            String name = parts[0];
            String id = parts[1];
            try {
                Long.parseLong(id);
            } catch (Exception e) {
                String a = name;
                name = id;
                id = a;
            }
            try {
                Long.parseLong(id);
            } catch (Exception e) {
                return null;
            }
            datainitialize.init();

            for (GetJudgeIpResultService getJudgeIpResultmap : getJudgeIpResultMaps) {
                StudentResult judgeIpResultMap = getJudgeIpResultmap.getJudgeIpResult(ipPort);
                StudentResult result = new StudentResult();
                result.setName(name);
                if (judgeIpResultMap != null) {
                    result.setItemNumber(judgeIpResultMap.getItemNumber());
                    result.setScore(judgeIpResultMap.getScore());
                    result.setResult(judgeIpResultMap.getResult());
                }
                result.setId(id);
                result.setIp(ip);
                result.setCreateTime(LocalDateTime.now());
                studentResultMapper.addStudentResult(result);
            }


            double totalScoreMax = 0;
            List<Double> scores = new ArrayList<>();
            List<StudentResult> studentScores = studentResultMapper.getStudentResultById(id);
            for (int number = 1; number <= 15; number++) {
                String Number = String.valueOf(number);
                double maxScore = studentScores.stream()
                        .filter(result -> Number.equals(result.getItemNumber()) && result.getScore() != null)
                        .mapToDouble(StudentResult::getScore)
                        .max()
                        .orElse(0.0);
                totalScoreMax += maxScore;
                scores.add(maxScore);
            }
            aS.setJudge1(scores.get(0));
            aS.setJudge2(scores.get(1));
            aS.setJudge3(scores.get(2));
            aS.setJudge4(scores.get(3));
            aS.setJudge5(scores.get(4));
            aS.setJudge6(scores.get(5));
            aS.setJudge7(scores.get(6));
            aS.setJudge8(scores.get(7));
            aS.setJudge9(scores.get(8));
            aS.setJudge10(scores.get(9));
            aS.setJudge11(scores.get(10));
            aS.setJudge12(scores.get(11));
            aS.setJudge13(scores.get(12));
            aS.setJudge14(scores.get(13));
            aS.setJudge15(scores.get(14));
            aS.setTotalScore(totalScoreMax);
            aS.setId(id);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return aS;
    }


    private AssessmentScore gradeJarFile(File jarFile) {
        String studentId = jarFile.getName().replace(".jar", "").split("-")[0];
        Process process = null;
        AssessmentScore score = new AssessmentScore();
        StringBuilder processOutput = new StringBuilder();
        try {
            // 启动JAR文件
            ProcessBuilder pb = new ProcessBuilder("C:\\Program Files\\Java\\jdk-17\\bin\\java", "-jar", jarFile.getAbsolutePath());
            pb.redirectErrorStream(true); // 合并错误流和输出流
            process = pb.start();

            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            BufferedWriter processInput = new BufferedWriter(new OutputStreamWriter(process.getOutputStream()));

            // 启动线程读取输出
            Thread outputReader = new Thread(() -> {
                try {
                    String line;
                    while ((line = reader.readLine()) != null) {
                        processOutput.append(line).append("\n");
                        // 可以在这里添加实时分析逻辑
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            });
            outputReader.start();

            Thread.sleep(15 * 1000);
            // 发送测试输入（如果有）
            score = testOne();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 确保进程被终止
            if (process != null && process.isAlive()) {
                process.destroyForcibly();
            }
        }
        if (score != null && !studentId.equals(score.getId())) {
            score.setName("学号不匹配：程序内学号"+score.getId());
        }
        score.setId(studentId);
        return score;
    }

}
